#include "bsp_4g_task.h"
#include "bsp_4g_common.h"
#include "cw32l010_sysctrl.h"
#include "cw32l010_uart.h"

void Gpio_4g_Init(void)
{
    __SYSCTRL_GPIOB_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    GPIO_InitStructure.Pins = EC800E_MODEL_PWR_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(EC800E_MODEL_PWR_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pins = EC800E_MODEL_RST_PIN;
    GPIO_Init(EC800E_MODEL_RST_PORT, &GPIO_InitStructure);

    EC_Device_Power_Low();
    EC_Device_Reset_Low();
}
/** 4g接口串口初始化
 * @brief
 *
 */
void usart_4g_init(void)
{
    UART2_DeInit();

    __SYSCTRL_UART2_CLK_ENABLE();
    __SYSCTRL_GPIOB_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Pins = GPIO_PIN_5;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
    GPIO_InitStructure.Pins = GPIO_PIN_6;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
    // UART TX RX 复用
    PB05_AFx_UART2TXD();
    PB06_AFx_UART2RXD();

    UART_InitTypeDef UART_InitStructure = {0};

    UART_InitStructure.UART_BaudRate = 115200;
    UART_InitStructure.UART_Over = UART_Over_16;
    UART_InitStructure.UART_Source = UART_Source_PCLK;
    UART_InitStructure.UART_UclkFreq = SystemCoreClock;
    UART_InitStructure.UART_StartBit = UART_StartBit_FE;
    UART_InitStructure.UART_StopBits = UART_StopBits_1;
    UART_InitStructure.UART_Parity = UART_Parity_No;
    UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
    UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;

    UART_Init(CW_UART2, &UART_InitStructure);

    UART_ClearITPendingBit(CW_UART2, UART_IT_RC | UART_IT_TXE | UART_IT_TC);
    UART_ITConfig(CW_UART2, UART_IT_RC, DISABLE);
    UART_ITConfig(CW_UART2, UART_IT_TC | UART_IT_TXE, DISABLE);

    // 优先级，无优先级分组
    NVIC_SetPriority(UART2_IRQn, 0);
    // UARTx中断使能
    NVIC_EnableIRQ(UART2_IRQn);
}

/** 串口2中断任务，用于基础数据收发
 * @brief
 *
 */
void UART2_IRQHandler(void)
{
    /* USER CODE BEGIN */
    if (UART_GetITStatus(CW_UART2, UART_IT_RC) != RESET && CW_UART2->IER_f.RC)
    {
        device_4g->current_read->buf[device_4g->current_read->length++] = UART_ReceiveData_8bit(CW_UART2);

        if (device_4g->current_read->length >= device_4g->read_buffer_size)
        {
            device_4g->current_read->status = DRV_4G_REC_STANDBY;
            // device_4g->current_read = device_4g->current_read->next;
        }

        UART_ClearITPendingBit(CW_UART2, UART_IT_RC);
    }

    if (UART_GetITStatus(CW_UART2, UART_IT_RXIDLE) != RESET && CW_UART2->IER_f.RXIDLE)
    {
        UART_ClearITPendingBit(CW_UART2, UART_IT_RXIDLE);
    }

    if (UART_GetITStatus(CW_UART2, UART_IT_TXE) != RESET && CW_UART2->IER_f.TXE)
    {
        if (device_4g->current_write->length)
        {
            if (device_4g->current_write->current < device_4g->current_write->length)
            {
                CW_UART2->TDR = device_4g->current_write->buf[device_4g->current_write->current++];
            }
            if (device_4g->current_write->current == device_4g->current_write->length)
            {
                UART_ITConfig(CW_UART2, UART_IT_TXE, DISABLE);
            }
        }
    }

    if (UART_GetITStatus(CW_UART2, UART_IT_TC) != RESET && CW_UART2->IER_f.TC)
    {
        UART_ClearITPendingBit(CW_UART2, UART_IT_TC);

        if (device_4g->current_write->current == device_4g->current_write->length)
        {
            device_4g->current_write->current = 0;
            device_4g->current_write->length = 0;
            device_4g->send_busy = 0;
            UART_ITConfig(CW_UART2, UART_IT_TC, DISABLE);
            UART_ITConfig(CW_UART2, UART_IT_RC | UART_IT_RXIDLE, ENABLE);
        }
    }
    /* USER CODE END */
}

/** 获取接收数据长度
 * @brief
 *
 * @return int
 */
int device_data_rec_length(void)
{
    return device_4g->current_read->length;
}

/** 重置4g串口接收
 * @brief
 *
 * @return int
 */
void device_data_rec_restart(void)
{
    device_4g->current_read->status = DRV_4G_REC_WRITING;
    device_4g->current_read->length = 0;
}

/** 重置接收
 * @brief
 *
 * @return int
 */
int devcie_data_rec_reset(void)
{
    rt_enter_critical();
    UART_ITConfig(CW_UART2, UART_IT_RC | UART_IT_RXIDLE, DISABLE);
    memset(device_4g->current_read->buf, 0, device_4g->read_buffer_size);
    device_4g->current_read->current = 0;
    device_4g->current_read->length = 0;
    device_4g->current_read->status = DRV_4G_REC_WRITING;
    rt_exit_critical();
    return 0;
}
/**
 * @brief
 *
 * @param buf 需要发送数据位置
 * @param length 需要发送数据长度
 * @return int 目前已发送长度
 */
int driver_4G_data_send(void *buf, int length)
{
    unsigned int Data_In_Length = 0;

    if (device_4g->send_busy)
        return -1;

    if (length > device_4g->send_buffer_size)
        Data_In_Length = device_4g->send_buffer_size;
    else
        Data_In_Length = length;

    device_4g->current_write->length = Data_In_Length;
    rt_memcpy(device_4g->current_write->buf, buf, Data_In_Length);
    UART_ITConfig(CW_UART2, UART_IT_TC | UART_IT_TXE, ENABLE);

    device_4g->send_busy = 50; // 500ms发送超时
    return length - Data_In_Length;
}

/** 发送命令,发送命令时，一问一答，接收完成不再接收数据
 * @brief
 *
 */
rec_4G_unit *SEND_CMD(char *cmd, int TIME)
{
    int wait_times = TIME;
    unsigned short templen, temp;
    device_4g->retytimes++;
    rec_4G_unit *unit = NULL;
    devcie_data_rec_reset();
    driver_4G_data_send(cmd, rt_strlen(cmd));
    rt_thread_mdelay(50); // 等待发送完成
    templen = 0;

    while (wait_times > 0)
    {
        temp = device_data_rec_length();
        if (templen != 0 && templen == temp)
        {
            rt_enter_critical();
            device_4g->current_read->status = DRV_4G_REC_STANDBY;
            unit = device_4g->current_read;
            //            device_4g->current_read = device_4g->current_read->next;
            rt_exit_critical();
            return unit;
        }
        else
        {
            rt_thread_mdelay(10);
            wait_times -= 10;
            templen = temp;
        }
    }
    return unit;
}

rec_4G_unit *SEND_CMD_DIRECT(char *cmd, int TIME)
{
    int wait_times = TIME;
    unsigned short templen, temp;
    device_4g->retytimes++;
    rec_4G_unit *unit = NULL;

    int length = rt_strlen(cmd);

    if (device_4g->send_busy)
        return unit;

    device_4g->current_write->length = length;
    device_4g->current_write->buf = cmd;
    UART_ITConfig(CW_UART2, UART_IT_TC | UART_IT_TXE, ENABLE);
    device_4g->send_busy = 50; // 500ms发送超时

    rt_thread_mdelay(50); // 等待发送完成
    templen = 0;

    while (wait_times > 0)
    {
        temp = device_data_rec_length();
        if (templen != 0 && templen == temp)
        {
            rt_enter_critical();
            device_4g->current_read->status = DRV_4G_REC_STANDBY;
            unit = device_4g->current_read;
            //            device_4g->current_read = device_4g->current_read->next;
            rt_exit_critical();
            return unit;
        }
        else
        {
            rt_thread_mdelay(10);
            wait_times -= 10;
            templen = temp;
        }
    }
    return unit;
}

/** 数据接收
 * @brief
 *
 * @param TIMEOUT
 */
rec_4G_unit *DATA_LISTEN(int TIMEOUT)
{
    int wait_times = TIMEOUT;
    device_4g->retytimes++;
    unsigned short templen, temp;
    rec_4G_unit *unit = NULL;
    devcie_data_rec_reset();
    templen = 0;
    while (wait_times > 0)
    {
        rt_thread_mdelay(20);
        temp = device_data_rec_length();
        if (templen != 0 && templen == temp)
        {
            rt_enter_critical();
            device_4g->current_read->status = DRV_4G_REC_STANDBY;
            unit = device_4g->current_read;
            //            device_4g->current_read = device_4g->current_read->next;
            rt_exit_critical();
            break;
        }
        wait_times -= 20;
        templen = temp;
    }
    return unit;
}

/** 数据解析器
 * @brief
 *
 * @param buf
 * @param length
 * @return _mqtt_datatrans_enum
 */
_mqtt_datatrans_enum mqtt_data_decode(void)
{
    DATA_LISTEN(1000);
    return MQTT_OK;
}

int DATA_TRIM(rec_4G_unit *unit)
{
    int relength = unit->length;
    if (relength <= 0)
        return 0;
    unit->buf[relength] = '\0';
    return relength;
}
